package com.crm.service.impl.cluePoolManager;


import com.alibaba.fastjson.JSONObject;
import com.crm.common.model.Enum.StatusCodeEnum;
import com.crm.dao.mapper.cluePoolManager.ClueMapper;
import com.crm.model.entity.cluePoolManager.*;
import com.crm.dao.mapper.customMapper.cluePoolManagerCustomMapper.ClueCustomMapper;
import com.crm.model.entity.customerManager.Customer;
import com.crm.model.entity.sys.UserAccount;
import com.crm.model.qo.cluePoolManager.ClueExtentQO;
import com.crm.model.qo.cluePoolManager.ClueQO;
import com.crm.model.qo.cluePoolManager.ClueSeniorQO;
import com.crm.model.vo.cluePoolManager.ClueVO;
import com.crm.model.vo.cluePoolManager.UserCompanyVO;
import com.crm.redis.service.cluePoolManager.ClueRedisService;
import com.crm.service.cluePoolManager.ClueDbService;
import com.crm.service.cluePoolManager.ClueReceiveDbService;
import com.crm.service.customerManager.CustomerDbService;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author yincuimei
 * @Date 2020/12/24 11:12
 */
@Service
@Transactional(rollbackFor = {RuntimeException.class, Error.class})
public class ClueDbServiceImpl implements ClueDbService {

    @Autowired
    private ClueMapper clueMapper;

    @Autowired
    private ClueCustomMapper clueCustomMapper;

    @Autowired
    private ClueReceiveDbService clueReceiveDbService;

    @Autowired
    private CustomerDbService customerDbService;

    @Autowired
    private ClueRedisService clueRedisService;

    /**
     * 私有池、分公司公有池、全国公有池的线索清单
     * @param clueQO        ---普通搜索条件
     * @param clueSeniorQO  ---高级搜索条件(包括行业、成立年限、注册资本、企业类型、参保人数、有无联系电话、有无联系人、有无联系邮箱)
     * @return
     */
    @Override
    public List<ClueVO> selectPublicPoolClueList(ClueQO clueQO,ClueSeniorQO clueSeniorQO,String orderStr) {
        return clueCustomMapper.selectPublicPoolClueList(clueQO,clueSeniorQO,orderStr);
    }

    /**
     * 个人池线索的线索清单(包括个人默认池、个人创建的线索池)
     * @param clueQO    ---普通搜索条件
     * @param orderStr  ---高级搜索条件(包括行业、成立年限、注册资本、企业类型、参保人数、有无联系电话、有无联系人、有无联系邮箱)
     * @return
     */
    @Override
    public List<ClueVO> selectPrivatePoolClueList(ClueQO clueQO,ClueSeniorQO clueSeniorQO,String orderStr) {
        return clueCustomMapper.selectPrivatePoolClueList(clueQO,clueSeniorQO,orderStr);
    }

    /**
     * 根据线索池ID查询该线索池里线索的已分配和已领取总数(私有池、分公司公有池、全国公有池)
     * @param cluePoolPublicId ---线索池ID
     * @return
     */
    public long selectDistributedOrReceiveCount(String cluePoolPublicId){
        return clueCustomMapper.selectDistributedOrReceiveCount(cluePoolPublicId);
    }

    /**
     * 根据线索池ID查询未删除的线索
     * @param cluePoolPublicId  --- 线索池公有id
     * @return
     */
    @Override
    public List<Clue> selectClueList(String cluePoolPublicId) {
        return null;
    }

    /**
     * 线索--分配
     * @param clue
     * @return
     */
    @Override
    public int updateClueDistribute(Clue clue) {
        int num = clueMapper.updateByPrimaryKeySelective(clue);
        if(num>0){
            Clue clueRedis = selectClueByClueId(clue.getClueId());
            if(clueRedis!=null){
                clueRedisService.deleteClueById(clue.getClueId());
                clueRedisService.deleteClueByCompanyNameAndCode(clueRedis.getCompanyName(),clueRedis.getUnifiedSocialCreditCode());
            }
        }

        return num;
    }


    /**
     * 根据个人线索池Id查询所分配的线索条数
     * @param cluePoolPrivateId  ---线索池私有id
     * @return
     */
    public long selectCluePrivateCount(String cluePoolPrivateId){
        ClueExample clueExample = new ClueExample();
        ClueExample.Criteria criteria = clueExample.createCriteria();
        criteria.andCluePoolPrivateIdEqualTo(cluePoolPrivateId);
        criteria.andDeleteStatusEqualTo((short)StatusCodeEnum.NORMAL_CODE.getState());
        long count = clueMapper.countByExample(clueExample);
        return count;
    }


    /**
     * 线索--收回
     * @param clueQO
     * @return
     */
    @Override
    public int updateClueState(ClueQO clueQO) {
        int num = clueCustomMapper.updateClueState(clueQO);
        if(num>0){
            Clue clue = selectClueByClueId(clueQO.getClueId());
            if(clue!=null){
                clueRedisService.deleteClueById(clueQO.getClueId());
                clueRedisService.deleteClueByCompanyNameAndCode(clue.getCompanyName(),clue.getUnifiedSocialCreditCode());
            }

        }
        return num;
    }

    /**
     * 线索--删除
     * @param clueQO
     * @return
     */
    @Override
    public int updateDeleteStatusById(ClueQO clueQO ) {
        int num = clueCustomMapper.updateDeleteStatusById(clueQO);
        if(num>0){
            Clue clueRedis = selectClueByClueId(clueQO.getClueId());
            if(clueRedis!=null){
                clueRedisService.deleteClueById(clueQO.getClueId());
                clueRedisService.deleteClueByCompanyNameAndCode(clueRedis.getCompanyName(),clueRedis.getUnifiedSocialCreditCode());
            }
        }
        return num;
    }

    /**
     * 管理系统--批量删除线索(将delete_status置为1)
     * @param clueIds
     * @param clueQO
     * @return
     */
    @Override
    public Boolean batchDeleteClueByClueIds(List clueIds, ClueQO clueQO) {
        int num = clueCustomMapper.batchDeleteClueByClueIds(clueIds,clueQO);
        if(num>0){
            clueIds.stream().forEach(clueId ->{
                Clue clueRedis = selectClueByClueId(clueId.toString());
                if(clueRedis!=null){
                    clueRedisService.deleteClueById(clueId.toString());
                    clueRedisService.deleteClueByCompanyNameAndCode(clueRedis.getCompanyName(),clueRedis.getUnifiedSocialCreditCode());
                }
            });
        }
        return num > 0;
    }

    /**
     * 根据线索池ID查询公司
     * @param cluePollId  ---线索池ID
     * @return
     */
    @Override
    public   List<UserCompanyVO>  selectDistributeCompany(String cluePollId) {
        return clueCustomMapper.selectDistributeCompany(cluePollId,(short)StatusCodeEnum.NORMAL_CODE.getState());
    }

    /**
     * 根据用户名查询用户信息及所在公司信息(全国公有池、分公司公有池-分配-按人员姓名模糊查找)
     * @param userName ---用户名
     * @return
     */
    @Override
    public List<UserCompanyVO> selectUserAndCompany(String userName) {
        return clueCustomMapper.selectUserAndCompany(userName);
    }

    /**
     * 查询分公司公有池的用户
     * @param companyIds ---公司ID集合
     * @return
     */
    @Override
    public  List<UserCompanyVO> selectUserByPoolPermission(List<String> companyIds,String userName) {
        return clueCustomMapper.selectUserByPoolPermission(companyIds,userName);
    }

    @Override
    public Boolean insertClue(Clue clue) {
        Boolean result = false;
        int num = clueMapper.insertSelective(clue);
        if(num>0){
            result=true;
        }
        return result;
    }

    @Override
    public long selectCluePublicCount(String cluePoolPublicId) {
        ClueExample clueExample = new ClueExample();
        ClueExample.Criteria criteria = clueExample.createCriteria();
        criteria.andCluePoolPublicIdEqualTo(cluePoolPublicId);
        criteria.andDeleteStatusEqualTo(Short.parseShort(String.valueOf(StatusCodeEnum.NORMAL_CODE.getState())));
        long num = clueMapper.countByExample(clueExample);
        return num;
    }

    @Override
    public Boolean selectClueIfRepeated(String companyName, String unifiedSocialCreditCode) {
        Boolean result = false;
        //先在redis中查询私有线索池信息，若没有则在数据库中查询，再插入到redis中
        Clue clue = clueRedisService.getClueByCompanyNameAndCode(companyName, unifiedSocialCreditCode);
        if (clue == null) {
            ClueExample clueExample = new ClueExample();
            ClueExample.Criteria criteria = clueExample.createCriteria();
            criteria.andCompanyNameEqualTo(companyName);
            criteria.andUnifiedSocialCreditCodeEqualTo(unifiedSocialCreditCode);
            criteria.andDeleteStatusEqualTo(Short.parseShort(String.valueOf(StatusCodeEnum.NORMAL_CODE.getState())));
            List<Clue> clues = clueMapper.selectByExample(clueExample);
            if(clues.size()>0){
                result = true;
                clueRedisService.setClueByCompanyNameAndCode(clues.get(0));
            }else {
                result = false;
            }
        }else {
            result = true;
        }

        //判断客户是否存在
      if(result==false){
          Customer customer = customerDbService.isCustomerRepeat(companyName,unifiedSocialCreditCode);
            if(customer!=null){
                result = true;
            }
        }
        return result;
    }

    @Override
    public Boolean updateClue(Clue clue) {
        Boolean result = false;
        int num = clueMapper.updateByPrimaryKeyWithBLOBs(clue);
        if(num>0){
            Clue clueById = clueRedisService.getClueById(clue.getClueId());
            if(clueById!=null){
                clueRedisService.deleteClueById(clue.getClueId());
                clueRedisService.deleteClueByCompanyNameAndCode(clueById.getCompanyName(),clueById.getUnifiedSocialCreditCode());
            }
            result=true;
        }
        return result;
    }

    @Override
    public Boolean selectIsClueRepeated(String companyName, String unifiedSocialCreditCode, String clueId) {
        Boolean result = false;
        ClueExample clueExample = new ClueExample();
        ClueExample.Criteria criteria = clueExample.createCriteria();
        criteria.andCompanyNameEqualTo(companyName);
        criteria.andUnifiedSocialCreditCodeEqualTo(unifiedSocialCreditCode);
        criteria.andClueIdNotEqualTo(clueId);
        criteria.andDeleteStatusEqualTo(Short.parseShort(String.valueOf(StatusCodeEnum.NORMAL_CODE.getState())));
        List<Clue> clues = clueMapper.selectByExample(clueExample);
        if(clues.size()>0){
            result = true;
        }
        return result;
    }

    @Override
    public Clue selectClueByClueId(String clueId) {
        //先在redis中查询线索信息，若没有则在数据库中查询，插入到redis中
        Clue clue = clueRedisService.getClueById(clueId);
        if (clue == null) {
            clue = clueMapper.selectByPrimaryKey(clueId);
            if (clue != null) {
                clueRedisService.setClueById(clue);
            }
        }
        return clue;
    }

    /**
     * @author wll
     * info-线索池公海-线索清单
     */
    @Override
    public List<ClueVO> selectClueInfo(ClueQO clueQO, String orderStr,String source) {
        return clueCustomMapper.selectClueInfo(clueQO,orderStr,source);
    }

    /**
     *info 用户模块-我的线索池-线索清单
     * @return
     */
    @Override
    public List<ClueVO> getMyClueList(ClueQO clueQO, ClueExtentQO clueExtentQO, String orderStr, String dictionaryEnum) {
        return clueCustomMapper.getMyClueList(clueQO, clueExtentQO, orderStr,dictionaryEnum);
    }

    /**
     *info 用户模块-我的线索池-线索清单-释放线索
     */
    @Override
    public Boolean modifyClueData(Map map) {
        int result = clueCustomMapper.modifyClueData(map);
        return result > 0;

    }

    @Override
    public long selectCluePoolPrivateCount(String cluePoolPrivateId) {
        ClueExample clueExample = new ClueExample();
        List list = new ArrayList();
        list.add(1);
        list.add(2);
        ClueExample.Criteria criteria = clueExample.createCriteria();
        criteria.andCluePoolPrivateIdEqualTo(cluePoolPrivateId);
        criteria.andClueStateIn(list);//1-已领取；2-已分配
        criteria.andDeleteStatusEqualTo(Short.parseShort(String.valueOf(StatusCodeEnum.NORMAL_CODE.getState())));
        long num = clueMapper.countByExample(clueExample);
        return num;
    }


    /**
     * @author wll
     * info 查询当前线索状态是否在池(公海里的线索同一时间可以很多人操作同一条线索) 删除状态是否正常
     * return true该条线索未被领取 false该条线索已被领取
     */
    @Override
    public JSONObject checkClueIsInThePool(ClueQO clueQO) {
        JSONObject result = new JSONObject();
        ClueExample clueExample = new ClueExample();
        ClueExample.Criteria criteria = clueExample.createCriteria();
        criteria.andClueIdEqualTo(clueQO.getClueId());//线索id
        criteria.andClueStateEqualTo(0);//线索状态：0-在池；1-已领取；2-已分配
        criteria.andDeleteStatusEqualTo(Short.parseShort("0"));//删除状态---0: 正常; 1: 已删除
        List<Clue> clues = clueMapper.selectByExample(clueExample);
        if(null !=clues && clues.size()>0){
            result.put("status",true);
            return result;
        }else{
            result.put("status",false);
            result.put("toast","该条线索已被领取");
            return result;
        }
    }

    /**
     * @author wll
     * info 线索领取到个人默认池 同时添加领取记录
     * param cluePoolPrivate个人默认池信息
     * param  clueQO 线索信息
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Error.class})
    public JSONObject getClueToThePersonalDefaultPool(CluePoolPrivate cluePoolPrivate, ClueQO clueQO,String poolId) {
        JSONObject result = new JSONObject();
        Map map = new HashMap();
        UserAccount userAccount = (UserAccount) SecurityUtils.getSubject().getPrincipal();//获取登录人信息
        map.put("clueState",1); //线索状态：0-在池；1-已领取；2-已分配
        map.put("cluePoolPrivateId",cluePoolPrivate.getCluePoolPrivateId());//个人默认池id
        map.put("clueId",clueQO.getClueId());//当前线索id
        map.put("updateTm",new Date());//更新时间
        map.put("updatePeopleId",userAccount.getAccountId());//更新人
            //领取线索到个人默认池里
            int num = clueCustomMapper.modifyClueDataToPersonalDefaultPool(map);
            if(num>0){
                //添加领取记录
                Boolean status = clueReceiveDbService.insertClueReceive(poolId,cluePoolPrivate.getCluePoolPrivateId(),clueQO.getClueId(),userAccount.getAccountId(),1);
                if(status){
                    result.put("status",true);
                    return result;
                }else{
                    result.put("status",false);
                    result.put("toast","线索领取失败");
                    return result;
                }
            }else{
                result.put("status",false);
                result.put("toast","线索领取失败");
                return result;
            }


    }

    @Override
    public long clueZeroTimeReceiveCount(String cluePoolId) {
        long num = clueCustomMapper.clueZeroTimeReceiveCount(cluePoolId);
        return num;
    }

    /**
     * 线索总转化数
     * @param cluePoolPublicId  线索池公有id
     * @return
     */
    @Override
    public long selectClueConverCountByPublicPoolId(String cluePoolPublicId) {
        ClueExample clueExample = new ClueExample();
        ClueExample.Criteria criteria = clueExample.createCriteria();
        criteria.andCluePoolPublicIdEqualTo(cluePoolPublicId);
        criteria.andClueStateEqualTo(3);  //线索状态：0-在池；1-已领取；2-已分配 ;3-已转化
        criteria.andDeleteStatusEqualTo(Short.parseShort(String.valueOf(StatusCodeEnum.NORMAL_CODE.getState())));
        long num = clueMapper.countByExample(clueExample);
        return num;
    }


    @Override
    public Clue selectOneClue() {
        return clueCustomMapper.selectOneClue();
    }

    /***
     * @Description:按每月查询线索转化统计
     * @Param: cluePoolId 线索池id
     * @Param: yearMonth 年月
     * @Author: luojie
     * @Date: 2021/5/13 15:07
     */
    @Override
    public long getCluePoolConversionStatisticsForOneMonth(String cluePoolId, String yearMonth) throws ParseException {
        long result = clueCustomMapper.selectCluePoolConversionStatisticsForOneMonth(cluePoolId,yearMonth);
        return result;
    }

    @Override
    public int batchInsertClue(List<Clue> clueList) {
        int result = clueCustomMapper.batchInsertClue(clueList);
        return result;
    }

    @Override
    public int updateUserClueTag(String tag, String clueId) {
        int result = clueCustomMapper.updateUserClueTag(tag, clueId);
        return result;
    }
}
